package com.fine.hair.manage.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fine.hair.comm.dto.*;
import com.fine.hair.comm.enums.OrderStatus;
import com.fine.hair.comm.enums.RewardsPunishmentType;
import com.fine.hair.comm.exception.BusinessException;
import com.fine.hair.comm.model.*;
import com.fine.hair.comm.utils.ApiResponse;
import com.fine.hair.comm.utils.MyStatus;
import com.fine.hair.comm.utils.PageInfo;
import com.fine.hair.comm.vo.TodayPerformanceVo;
import com.fine.hair.manage.mapper.*;
import com.fine.hair.manage.util.JwtUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * <p>门店相关接口</p>
 *
 * @author mouseyCat
 * @date 2020/10/24 17:57
 */
@Api(tags = {"门店相关接口"})
@RestController
@RequestMapping("/branch/")
public class BranchController {

    @Resource
    private BranchMapper branchMapper;

    @Autowired
    private Snowflake snowflake;

    @Resource
    private OrderMapper orderMapper;

    @Resource
    private UserMapper userMapper;

    @Autowired
    private JwtUtil jwtUtil;

    @Resource
    private SecUserMapper secUserMapper;

    @Resource
    private RewardsPunishmentMapper rewardsPunishmentMapper;

    @ApiOperation("门店列表")
    @PostMapping("branch-list")
    public ApiResponse<IPage<Branch>> branchList(HttpServletRequest request, @RequestBody BranchListDto dto) {
        String username = jwtUtil.getUsernameFromJWT(jwtUtil.getJwtFromRequest(request));
        SecUser secUser = secUserMapper.selectByUsername(username);
        PageInfo<Branch> branchPage = new PageInfo<>(dto.getPageCurr(), dto.getPageSize());
        if (secUser.getRoleId() == 1) {
            IPage<Branch> branchIPage = branchMapper.selectPage(branchPage, new LambdaQueryWrapper<Branch>().like(Branch::getTitle, dto.getBranchName()));
            return ApiResponse.ofSuccess(branchIPage);
        } else if (secUser.getRoleId() == 3) {
            // 筛选门店
            //List<String> branchIds = Arrays.asList(secUser.getBranchId().split(","));
            IPage<Branch> branchIPage = branchMapper.selectPage(branchPage,
                    new LambdaQueryWrapper<Branch>().eq(Branch::getId, secUser.getBranchId()).like(Branch::getTitle, dto.getBranchName()));
            return ApiResponse.ofSuccess(branchIPage);
        } else {
            // 不返回任何数据
            IPage<Branch> branchIPage = branchMapper.selectPage(branchPage,
                    new LambdaQueryWrapper<Branch>().eq(Branch::getId, 0));
            return ApiResponse.ofSuccess(branchIPage);
        }
    }

    @ApiOperation("新增门店")
    @PostMapping("add-branch")
    public ApiResponse addBranch(@RequestBody AddBranchDto dto) {
        Branch branch = new Branch();
        BeanUtil.copyProperties(dto, branch);
        branch.setId(snowflake.nextId());
        branchMapper.insert(branch);
        return ApiResponse.ofSuccess();
    }

    @ApiOperation("编辑门店")
    @PostMapping("alter-branch")
    public ApiResponse alterBranch(@RequestBody AddBranchDto dto) {
        Branch branch = branchMapper.selectById(dto.getId());
        BeanUtil.copyProperties(dto, branch);
        branchMapper.updateById(branch);
        return ApiResponse.ofSuccess();
    }

    @ApiOperation("删除门店")
    @DeleteMapping("del-branch/{branchId}")
    public ApiResponse delBranch(@PathVariable String branchId) {
        // 检查该门店下是否还存在订单，存在订单则不让删除
        List<Order> orders =
                orderMapper.selectList(new LambdaQueryWrapper<Order>().eq(Order::getBranchId, branchId).eq(Order::getStatus,
                        OrderStatus.WILL_COMPLETE.getCode()));
        if (orders.size() > 0) {
            return ApiResponse.ofStatus(MyStatus.REJECT_DELETE_BRANCH);
        }
        branchMapper.deleteById(branchId);
        return ApiResponse.ofSuccess();
    }

    @PostMapping("staff-list")
    @ApiOperation("门店员工列表")
    public ApiResponse<Page<User>> staffList(@RequestBody StaffListDto dto) {
        Page<User> userPage = new Page<>(dto.getPageCurr(), dto.getPageSize());
        List<User> userList = userMapper.selectStaffList(userPage, dto.getBranchId(), dto.getPhoneOrName());
        userPage.setRecords(userList);
        return ApiResponse.ofSuccess(userPage);
    }


    @GetMapping("staff-base-info/{staffId}")
    @ApiOperation("员工基本信息")
    public ApiResponse<User> staffBaseInfo(@PathVariable String staffId) {
        return ApiResponse.ofSuccess(userMapper.selectById(staffId));
    }

    @PostMapping("staff-rewards-punishment-info")
    @ApiOperation("员工奖惩信息")
    public ApiResponse<PageInfo<RewardsPunishment>> staffRewardsPunishmentInfo(@RequestBody StaffRewardsPunishmentInfoDto dto) {
        PageInfo<RewardsPunishment> pageInfo = new PageInfo<>(dto.getPageCurr(), dto.getPageSize());
        List<RewardsPunishment> list = rewardsPunishmentMapper.selectStaffRewardsPunishmentInfoByCondition(dto, pageInfo);
        pageInfo.setRecords(list);
        return ApiResponse.ofSuccess(pageInfo);
    }

    /**
     * 处理查询时自定义的开始时间和结束时间
     *
     * @param start 日期 格式 yyyy-MM-dd
     * @param end   日期 格式 yyyy-MM-dd
     * @return 开始时间和结束时间的数组 下标0 为开始时间 下标1 为结束时间
     */
    public static String[] getCustomDayStartAndEnd(String start, String end) {
        // 兼容前端传 yyyy-MM-dd HH:mm:ss yyyy-MM-dd 两种情况
        String startTime = start.split(" ")[0] + " 00:00:00";
        String endTime = end.split(" ")[0] + " 23:59:59";
        String[] time = new String[2];
        time[0] = startTime;
        time[1] = endTime;
        return time;
    }

    @ApiOperation("今日业绩")
    @PostMapping("today-performance/{staffId}")
    public ApiResponse<TodayPerformanceVo> todayPerformance(@PathVariable String staffId, @RequestBody DateDto dto) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        User user = userMapper.selectById(staffId);
        if (StrUtil.isNotBlank(dto.getStart())) {
            // 处理 开始时间 和 结束时间
            String[] customDayStartAndEnd = getCustomDayStartAndEnd(dto.getStart(), dto.getEnd());
            dto.setStart(customDayStartAndEnd[0]);
            dto.setEnd(customDayStartAndEnd[1]);
        }
        // 当日订单
        List<Order> orders = orderMapper.selectOrderByDate(df.format(new Date()), dto);

        // 当日店均
        BigDecimal branchAllMoney = orders.stream().filter(o -> o.getBranchId().equals(user.getBranchId().toString())).map(Order::getItemPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
        // 当日接单客户
        long orderCount = orders.stream().filter(o -> o.getTechnicianId().equals(staffId.toString())).count();

        // 人均
        long personCount =
                orders.stream().filter(o -> o.getBranchId().equals(user.getBranchId().toString())).map(Order::getUserId).distinct().count();
        BigDecimal personAvg;
        if (personCount == 0) {
            personAvg = BigDecimal.ZERO;
        } else {
            personAvg = branchAllMoney.divide(new BigDecimal(String.valueOf(personCount)), 2, BigDecimal.ROUND_HALF_UP);
        }
        // 当日奖惩列表
        List<RewardsPunishment> rewardsPunishments =
                rewardsPunishmentMapper.selectByDate(df.format(new Date()), dto);
        // 当日提成
        BigDecimal pm = rewardsPunishments.stream().filter(r -> r.getUserId().equals(staffId)).filter(r -> r.getType().equals(RewardsPunishmentType.PROPORTION.getCode())).map(RewardsPunishment::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        // 奖励金额
        BigDecimal rewards = rewardsPunishments.stream().filter(r -> r.getUserId().equals(staffId)).filter(r -> r.getType().equals(RewardsPunishmentType.AWARD.getCode())).map(RewardsPunishment::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        // 惩罚金额
        BigDecimal punishment = rewardsPunishments.stream().filter(r -> r.getUserId().equals(staffId)).filter(r -> r.getType().equals(RewardsPunishmentType.PUNISHMENT.getCode())).map(RewardsPunishment::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        // 个人当日收入
        BigDecimal selfIncome = pm.add(rewards).subtract(punishment);
        TodayPerformanceVo vo = TodayPerformanceVo.builder()
                .orderCount(orderCount)
                .branchAllMoney(branchAllMoney)
                .personAvg(personAvg)
                .pm(pm)
                .punishment(punishment)
                .rewards(rewards)
                .selfIncome(selfIncome)
                .build();
        return ApiResponse.ofSuccess(vo);
    }

    @PostMapping("staff-order-info")
    @ApiOperation(value = "员工订单信息", tags = "后台可统计员工当日的个人所得和相关奖励罚款")
    public ApiResponse<PageInfo<Order>> staffOrderInfo(@RequestBody StaffOrderInfoDto dto) {
        PageInfo<Order> pageInfo = new PageInfo<>(dto.getPageCurr(), dto.getPageSize());
        List<Order> list = orderMapper.selectStaffOrderInfoByCondition(dto, pageInfo);
        pageInfo.setRecords(list);
        return ApiResponse.ofSuccess(pageInfo);
    }

    @PostMapping("add-staff-rewards-punishment")
    @ApiOperation("添加员工奖惩信息")
    public ApiResponse addStaffRewardsPunishment(@RequestBody AddStaffRewardsPunishmentDto dto) {
        RewardsPunishment po = new RewardsPunishment();
        po.setId(snowflake.nextId());
        BeanUtil.copyProperties(dto, po);
        User user = userMapper.selectById(dto.getUserId());
        if (ObjectUtil.isNull(user)) {
            throw new BusinessException("当前用户不存在");
        }
        po.setBranchId(user.getBranchId().toString());
        po.setChargeAmount(dto.getChargeAmount());
        rewardsPunishmentMapper.insert(po);
        return ApiResponse.ofSuccess();
    }

    @PostMapping("search-user")
    @ApiOperation(value = "查找用户", notes = "用于管理员添加员工时 搜索的时候用")
    public ApiResponse<List<User>> searchPerson(@RequestBody SearchPersonDto dto) {
        List<User> user = userMapper.selectByPhoneOrWechatName(dto.getPhoneOrWechatName(), dto.getPhoneOrWechatName());
        return ApiResponse.ofSuccess(user);
    }

    @PostMapping("add-staff")
    @ApiOperation(value = "添加员工", notes = "后台管理员添加员工到店")
    public ApiResponse addStaff(@RequestBody AddStaffDto dto) {
        User user = userMapper.selectById(dto.getUserId());
        if (ObjectUtil.isNull(user)) {
            throw new BusinessException("当前用户不存在");
        }
        if (null != user.getBranchId()) {
            return ApiResponse.ofFailed("此用户已成为员工");
        }
        user.setBranchId(Long.valueOf(dto.getBranchId()));
        user.setPutBranchId(dto.getBranchId());
        userMapper.updateById(user);
        return ApiResponse.ofSuccess();
    }


}
